﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Diagnostics;

namespace aaaSoft.SkinEngine.MyControls
{
    class MyTrackBar : NativeWindow, IMyControl
    {
        TrackBar tbBase;
        SkinEngine skinEng;
        int Value = 0;


        bool IsMouseDown = false;

        public MyTrackBar(TrackBar tb, SkinEngine skinEng)
        {
            tbBase = tb;
            this.skinEng = skinEng;
        }

        public void StopControlSkin()
        {
            tbBase.ValueChanged -= new EventHandler(tbBase_ValueChanged);
            tbBase.MouseDown -= new MouseEventHandler(tbBase_MouseDown);
            tbBase.MouseUp -= new MouseEventHandler(tbBase_MouseUp);
            tbBase.MouseMove -= new MouseEventHandler(tbBase_MouseMove);
            tbBase.MouseLeave -= new EventHandler(tbBase_MouseLeave);
            tbBase.MouseEnter -= new EventHandler(tbBase_MouseEnter);

            ReleaseHandle();
        }

        public void StartControlSkin()
        {
            Value = tbBase.Value;
            tbBase.ValueChanged += new EventHandler(tbBase_ValueChanged);
            tbBase.MouseDown += new MouseEventHandler(tbBase_MouseDown);
            tbBase.MouseUp += new MouseEventHandler(tbBase_MouseUp);
            tbBase.MouseMove += new MouseEventHandler(tbBase_MouseMove);
            tbBase.MouseLeave += new EventHandler(tbBase_MouseLeave);
            tbBase.MouseEnter += new EventHandler(tbBase_MouseEnter);

            AssignHandle(tbBase.Handle);
        }

        void tbBase_MouseEnter(object sender, EventArgs e)
        {
            IsMouseDown = false;
        }

        void tbBase_MouseLeave(object sender, EventArgs e)
        {
            IsMouseDown = false;
        }

        void tbBase_MouseMove(object sender, MouseEventArgs e)
        {
            if (!IsMouseDown) return;
            int x = e.Location.X;
            if (x < 0) x = 0;
            if (x > tbBase.Width) x = tbBase.Width;

            tbBase.Value = x * (tbBase.Maximum - tbBase.Minimum) / tbBase.Width;
            DrawTrackBar();
        }

        void tbBase_MouseUp(object sender, MouseEventArgs e)
        {
            IsMouseDown = false;
        }

        void tbBase_MouseDown(object sender, MouseEventArgs e)
        {
            IsMouseDown = true;
        }

        void tbBase_ValueChanged(object sender, EventArgs e)
        {
            Value = tbBase.Value;
        }

        
        protected override void WndProc(ref Message m)
        {
            //如果画背景，则退出
            if (m.Msg == SkinHelpers.UnsafeNativeMethods.NativeMethods.WM_ERASEBKGND) return;
            
            base.WndProc(ref m);

            if (m.Msg == SkinHelpers.UnsafeNativeMethods.NativeMethods.WM_PAINT)
            {
                DrawTrackBar();
            }
        }

        private void DrawTrackBar()
        {
            Graphics g = tbBase.CreateGraphics();
            g.SmoothingMode = SmoothingMode.AntiAlias;

            //填充背景
            g.FillRectangle(new SolidBrush(skinEng.BackColor), new Rectangle(0, 0, tbBase.Width + 10, tbBase.Height + 10));
            
            Int32 topOffset = (tbBase.Height - 6) / 2;
            Region MainBarRgn = new Region(new Rectangle(0, topOffset, tbBase.Width, 6));
            Region OtherRgn = new Region(new Rectangle(0, 0, tbBase.Width, tbBase.Height));
            OtherRgn.Exclude(MainBarRgn);
            OtherRgn.Union(new Rectangle(0, topOffset, 1, 1));
            OtherRgn.Union(new Rectangle(tbBase.Width - 1, topOffset, 1, 1));
            OtherRgn.Union(new Rectangle(0, topOffset + 6 - 1, 1, 1));
            OtherRgn.Union(new Rectangle(tbBase.Width - 1, topOffset + 6 - 1, 1, 1));


            g.Clip = MainBarRgn;
            RectangleF tmpRectF = g.ClipBounds;
            Rectangle tmpRect = new Rectangle((int)tmpRectF.X, (int)tmpRectF.Y, (int)tmpRectF.Width, (int)tmpRectF.Height);
            SkinHelpers.GraphicHelper.DrawRectButton(g, tmpRect, SkinHelpers.ColorHelper.GetDLColor(skinEng.BackColor), 1);

            g.Clip = OtherRgn;
            g.TranslateTransform(0 - tbBase.Left, 0 - tbBase.Top);

            g.ResetClip();
            g.ResetTransform();

            Int32 xoffset = tbBase.Width * Value / tbBase.Maximum;

            Int32 barWidth = (int)(tbBase.Height * 0.6);
            Rectangle rectBar = new Rectangle(xoffset - barWidth / 2, 0, barWidth, tbBase.Height - 1);
            GraphicsPath gp = new GraphicsPath();
            Point[] pts = new Point[6];
            pts[0] = new Point(rectBar.Left, rectBar.Top);
            pts[1] = new Point(rectBar.Right, rectBar.Top);
            pts[2] = new Point(rectBar.Right, rectBar.Top + rectBar.Height * 2 / 3);
            pts[3] = new Point(rectBar.Left + rectBar.Width / 2, rectBar.Bottom);
            pts[4] = new Point(rectBar.Left, rectBar.Top + rectBar.Height * 2 / 3);
            pts[5] = new Point(rectBar.Left, rectBar.Top);

            
            Color colorForm = SkinHelpers.ColorHelper.HSB2RGBColor(Value * 255 / tbBase.Maximum, 255, 50);
            gp.AddLines(pts);
            Pen barPen = new Pen(Color.White);
            barPen.Color = SkinHelpers.ColorHelper.GetDeeperColor(colorForm, 0.8F);
            barPen.Width = 1.5F;
            g.DrawPath(barPen, gp);
            LinearGradientBrush barBrush = new LinearGradientBrush(rectBar, Color.FromArgb(200, Color.White), Color.FromArgb(100, colorForm), LinearGradientMode.Vertical);
            g.FillPath(barBrush, gp);
        }
    }
}
